﻿using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;

namespace DevWeb.Biztalk.DeploymentSettings.Common
{
   public static  class Helpers
    {
        /// <summary>
        /// Serializes the data in the object to the designated file path
        /// </summary>
        /// <typeparam name="T">Type of Object to serialize</typeparam>
        /// <param name="dataToSerialize">Object to serialize</param>
        /// <param name="filePath">FilePath for the XML file</param>
        public static void Serialize<T>(T dataToSerialize, string filePath)
        {
            using (Stream stream = File.Open(filePath, FileMode.Create, FileAccess.ReadWrite))
            {
                var serializer = new XmlSerializer(typeof(T));
                var writer = new XmlTextWriter(stream, Encoding.Default) {Formatting = Formatting.Indented};
                serializer.Serialize(writer, dataToSerialize);
                writer.Close();
            }
        }

       /// <summary>
       /// Serializes the data in the object to the designated file path
       /// </summary>
       /// <typeparam name="T">Type of Object to serialize</typeparam>
       /// <param name="dataToSerialize">Object to serialize</param>
       public static XElement XmlSerialize<T>(T dataToSerialize)
        {
            XElement serialiseToDocument;
            var serializer = new XmlSerializer(typeof(T), Constants.TargetNamespace);
            using (var stream = new MemoryStream())
            {
                serializer.Serialize(stream, dataToSerialize);
                stream.Flush();
                stream.Seek(0, SeekOrigin.Begin);

                serialiseToDocument = XElement.Load(stream);

                return serialiseToDocument;
            }

        }

        public static Stream BinarySerialize<T>(T dataToSerialize, Stream stream)
        {
            var bformatter = new BinaryFormatter();
            bformatter.Serialize(stream,dataToSerialize);
                
            stream.Position = 0;
            return stream;
        }

       /// <summary>
       /// Deserializes the data in the stream into an object
       /// </summary>
       /// <typeparam name="T">Type of object to deserialize</typeparam>
       /// <returns>Object containing deserialized data</returns>
       public static T XmlDeserialize<T>(XElement objectdocument)
        {
           var serializer = new XmlSerializer(typeof(T), Constants.TargetNamespace);
           T serializedData;
                
           var ms = new MemoryStream();
           var xws = new XmlWriterSettings {OmitXmlDeclaration = true, Indent = true};

           using (var xw = XmlWriter.Create(ms, xws))
           {
                    
               objectdocument.WriteTo(xw);
                    
           }
           using (ms)
           {
               ms.Flush();
               ms.Seek(0, SeekOrigin.Begin);
               serializedData = (T)serializer.Deserialize(ms);


                        
           }
           return serializedData;
        }
        /// <summary>
        /// Deserializes the data in the XML file into an object
        /// </summary>
        /// <typeparam name="T">Type of object to deserialize</typeparam>
        /// <param name="filePath">FilePath to XML file</param>
        /// <returns>Object containing deserialized data</returns>
        public static T XmlDeserialize<T>(string filePath)
        {
            var serializer = new XmlSerializer(typeof(T));
            T serializedData;

            using (Stream stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
            {
                serializedData = (T)serializer.Deserialize(stream);
            }

            return serializedData;
        }

        /// <summary>
        /// Deserializes the data in the stream into an object
        /// </summary>
        /// <typeparam name="T">Type of object to deserialize</typeparam>
        /// <param name="stream">Stream </param>
        /// <returns>Object containing deserialized data</returns>
        public static T BinaryDeserialize<T>(Stream stream)
        {
            var binaryFormatter = new BinaryFormatter();

            var serializedData = default(T);

            if (stream != null)
                using (stream)
                {
                    serializedData = (T)binaryFormatter.Deserialize(stream);



                }
            return serializedData;
        }








    }
}
